/** 主程序 */
(function(window , document) {

    // version

    // 提示图标
    var errIcon = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1619765206874" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3297" width="32" height="32" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M512 0C230.4 0 0 230.4 0 512s230.4 512 512 512 512-230.4 512-512-230.4-512-512-512zM448 256h128v128H448V256z m192 512H384v-64h64V512H384V448h192v256h64v64z" fill="#FF6600" p-id="3298"></path></svg>';
    
    // 获取全局的变量
    var options = window.kwdoc || {};
    // 默认加载的文件
    var home = options.home||'documents/home';
    var slider_name = options.slider_name || '首页';
    // 获取渲染容器
    var appContainer = document.getElementById('app');
    if(!appContainer) {
        // 找不到容器
        _errorTips('找不到展示内容的容器');
        return;
    }

    /**
     * 获取文档内容
     * @param {*} onSucc 请求成功后的回调
     * @param {*} onError 请求处理失败后的回调
     * @returns 
     */
    function _docLoad(url, onSucc , onError) {
        if(!url) {
            if(typeof onError == 'function') {
                onError('找不到文档路径');
            } else {
                _errorTips('找不到文档路径');
            }
            return;
        }

        var xhr = new XMLHttpRequest();
        xhr.onreadystatechange=function (){
            if(xhr.readyState==4){
                if(xhr.status >= 200 && xhr.status < 300) {
                    // 成功
                    var result = xhr.responseText;
                    if(typeof onSucc === 'function') {
                        onSucc(result);
                    }
                } else {
                    // 错误
                    if(typeof onError == 'function') {
                        onError(xhr.responseText);
                    } else {
                        _errorTips(xhr.responseText);
                    }
                }
                
            }
        };
        xhr.open("GET", url);
        xhr.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
        xhr.send();
    }

    /**
     * 获取预加载的文件，常用于加载第三方插件
     * @param {*} callback
     * @returns 
     */
    function _handlePreLoads(callback) {
        // 未设置 返回不执行
        if(!options.preloads) {
            // 执行回调
            callback && callback();
            return;
        }

        // 是否加载完成
        function _chechPreLoadFinish() {
            if(checkCount == 0) {
                // 加载完成，执行回调
                callback && callback();
            }
        }

        var checkCount = 0;
        var preloads = options.preloads;
        for(var key in  preloads) {
            var loaderItems = preloads[key] || [];
            // 计算需要加载的列表长度
            checkCount += loaderItems.length;
            for(var i=0; i<loaderItems.length; i++) {
                if(loaderItems[i].src) {
                    // 加载js脚本
                    var loadUrl = loaderItems[i].src;
                    delete loaderItems[i].src;
                    _addScript(loadUrl , function() {
                        checkCount --;
                        _chechPreLoadFinish(callback);
                    }, loaderItems[i]);
                    
                } else if(loaderItems[i].href) {
                    // 加载css脚本
                    var loadUrl = loaderItems[i].href;
                    delete loaderItems[i].href;
                    _addLink(loadUrl , function() {
                        checkCount --;
                        _chechPreLoadFinish(callback);
                    }, loaderItems[i]);

                }
            }
        }
    }

    //======== dom操作 ===========
    /**
     * 查找dom
     * @param {*} flag 查找的标识
     * @returns 返回匹配的节点集合
     */
    function find(flag) {
        return document.querySelectorAll(flag);
    }
    /**
     * 创建DOM节点
     * @param {*} name HTML标签名称 div a span ...
     * @param {*} options 属性
     * @returns 返回匹配的节点集合
     */
    function createElement(name , options) {
        options = options || {};
        var nodeObj = document.createElement(name);
        for(var key in options) {
            nodeObj[key] = options[key];
        }
        return nodeObj;
    }
    /**
     * 设置或者返回匹配DOM节点的属性
     * @param {*} el 
     * @param {*} name 属性名称
     * @param {*} value 属性值
     * @returns 
     */
    function attrs(el , name , value) {
        if(!el || !name) { return; }
        if(value) {
            for(var i=0; i<el.length; i++) {
                el[i].setAttribute(name , value);
            }
            return true;
        } else {
            var attrs = [];
            for(var i=0; i<el.length; i++) {
                attrs.push(el[i].getAttribute(name));
            }
            if(attrs.length == 1) {
                return attrs[0];
            }
            return attrs;
        }
    }

    /**
     * 绑定事件
     * @param {*} els 元素集合
     * @param {*} type 事件类型
     * @param {*} callback 回调
     */
    function bindEvent(els , type , callback) {
        if(typeof callback === 'undefined') {
            return;
        }
        for(var i=0; i<els.length; i++) {
            els[i].removeEventListener(type , callback);
            els[i].addEventListener(type , callback , false);
        }
    }

    // 加载字典
    var loaders = {};
    // 加载脚本
    function _addScript(url , callback, attrs) {
        if(loaders[url]) { return; }
        attrs = attrs || {};
        attrs.src = url;
        var scripts = find('script');
        var scriptNode = createElement('script' , attrs);
        scriptNode.onload = function() {
            loaders[url] = true;
            callback && callback();
        };
        scripts[scripts.length-1].parentNode.appendChild(scriptNode);
        
    }
    // 加载样式
    function _addLink(url , callback, attrs) {
        if(loaders[url]) { return; }
        attrs = attrs || {};
        attrs.href = url;
        attrs.rel = "stylesheet";
        var links = find('link');
        var linkNode = createElement('link' , attrs);
        for(var key in attrs) {
            linkNode[key] = attrs[key];
        }
        linkNode.onload = function() {
            loaders[url] = true;
            callback && callback();
        };
        links[links.length-1].parentNode.appendChild(linkNode);
    }
    // 设置错误内容提示
    function _errorTips(msg) {
        var errorNode = createElement('div' , {
            "innerHTML": errIcon + "&nbsp;&nbsp;" + msg,
            "style": "width:80%; margin: 20px auto 0 auto; text-align: center; color: #842029; background-color: #f8d7da; border-color: #f5c2c7; padding: 2rem; font-size: 30px;"
        });
        document.body.appendChild(errorNode);
    }

    /**
     * 提取一些需要执行的JS代码
     * @param {*} htmlCode 
     * @param {*} runcode 
     * @returns 
     */
    function _transformHTML(htmlCode, runcode) {
        var temp = document.createElement('div');
        temp.innerHTML = htmlCode;
        var runjs = temp.querySelectorAll('.language-runjs');
        for(var i=0; i<runjs.length; i++) {
            // 需要执行的JS代码
            runcode.push(runjs[i].innerHTML);
            // 替换成language-js 样式
            runjs[i].className = "language-js hljs javascript";
        }
        
        return temp.innerHTML;
    }

    var _executes = {};
    function _executeScript(runJS , index) {
        
        var tagId = 'run' + (index = index || 0);
        var runTag = document.getElementById('runJS');
        if(!_executes[tagId]) {
            _executes[tagId] = runJS.join("\r\n");
        }
        if(!runTag) {
            var scripts = find('script');
            runTag = createElement('script');
            runTag.innerHTML = _executes[tagId];
            scripts[scripts.length-1].parentNode.appendChild(runTag);
        } else {
            runTag.innerHTML = _executes[tagId]
        }
    }

    function _initPageEvent() {
        bindEvent(find('.home-nav, .nav-list li') , 'click', function(e) {
            console.log(e.target.dataset);
            window.title = e.target.innerText;
            location.hash = '#' + e.target.dataset.url;
        });
    }

    function _loadNavCont(url) {
        
        _docLoad(url , function(result) {
            // 文档加载成功
            var runJS = []; // 需要执行的JS代码清单
            var mainCont = document.querySelector('.main');
            // 渲染主体HTML
            var mdHtml = marked(result);
            mdHtml = _transformHTML(mdHtml, runJS);
            mainCont.innerHTML = '<div class="main-container">' + mdHtml + '</div>';

            // 所以链接点击之后新窗口打开
            var links = mainCont.getElementsByTagName('a');
            attrs(links , 'target' , '_blank');
            // 实现代码高亮
            if(typeof hljs !== 'undefined') {
                hljs.highlightAll();
            }

            // 所有需要加载的脚本都已经加载完成，再填充需要执行的JS代码
            _executeScript(runJS);

        }, function(errMsg) {
            // 文档加载失败
            _errorTips(errMsg);
        });
    }

    // 内容加载完毕，获取文档内容
    window.onload = function() {
        _handlePreLoads(function() {
            _docLoad(_getPath() , function(result) {
                // 文档加载成功
                var runJS = []; // 需要执行的JS代码清单
                var contents = []; // 内容列表

                // 渲染侧边栏
                var sidebars = options.sidebar || [];
                if(sidebars.length > 0) {
                    // 侧边显示
                    var aside = ['<aside><div class="home-nav" data-url="">' + slider_name + '</div><ul class="nav-list">'];
                    sidebars.forEach(function(item) {
                        aside.push('<li data-url="'+item.url+'">'+item.title+'</li>')
                    });
                    aside.push('</ul></aside>');
                    contents.push(aside.join(''));
                }

                if(typeof marked === 'undefined') {
                    _errorTips('Can not find Markdown Reader.');
                    return;
                }
                // 渲染主体HTML
                var mdHtml = marked(result);
                mdHtml = _transformHTML(mdHtml, runJS);
                contents.push('<div class="main"><div class="main-container">' + mdHtml + '</div></div>');
                appContainer.innerHTML = contents.join("");

                // 所以链接点击之后新窗口打开
                var links = appContainer.getElementsByTagName('a');
                attrs(links , 'target' , '_blank');
                // 实现代码高亮
                if(typeof hljs !== 'undefined') {
                    hljs.highlightAll();
                }

                // 所有需要加载的脚本都已经加载完成，再填充需要执行的JS代码
                _executeScript(runJS);

                // 初始化
                _initPageEvent();

                _loadVue();
            }, function(errMsg) {
                // 文档加载失败
                _errorTips(errMsg);
            });
        });
    }

    function _getPath() {
        var _hash = location.hash;
        return (_hash ? './' + _hash.replace('#' , '') : home) + '.md';
    }

    window.onhashchange = function() {
        _loadNavCont(_getPath());
    }
    function _loadVue() {
        var vuejs = document.querySelector('[vue-js]');
        if(vuejs) {
            _addScript('//cdn.jsdelivr.net/npm/vue@2.6.14' , function() {
                var scripts = find('script');
                var runVue = createElement('script');
                runVue.innerHTML = vuejs.innerHTML;
                scripts[scripts.length-1].parentNode.appendChild(runVue);
                vuejs.parentNode.removeChild(vuejs);
            });
        }
}

})(window , document);